import {Injectable} from '@angular/core';
import {
  ActivatedRouteSnapshot,
  CanActivate,
  CanActivateChild,
  Route,
  Router,
  RouterStateSnapshot
} from '@angular/router';
import {LoginService} from '../login.service';
import {isLogined} from '../../util/token.util';

/**
 * 在每次路由跳转的时候验证是否登陆
 * CanActivate：应用程序通常会根据访问者来决定是否授予某个特性区的访问权
 * CanActivateChild：会在任何子路由被激活之前运行
 * https://angular.cn/guide/router#canactivatechild-guarding-child-routes
 */
@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanActivateChild {

  // 不需要登陆验证的 URL
  RELEASE_URL: string[] = ['/login', '/register'];

  constructor(private router: Router, private loginService: LoginService) {
  }

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    const url: string = state.url;
    return this.checkLogin(url);
  }

  checkLogin(url: string): boolean {
    if (isLogined() || this.RELEASE_URL.indexOf(url) > -1) {
      return true;
    }

    // Store the attempted URL for redirecting
    this.loginService.redirectUrl = url;

    // Navigate to the login page with extras
    this.router.navigate(['/login']);
    return false;
  }

  // 保护所有子路由
  canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    return this.canActivate(route, state);
  }

  /**
   * 你已经使用 CanActivate 保护 AdminModule 了，它会阻止未授权用户访问管理特性区。如果用户未登录，它就会跳转到登录页。
   * 但是路由器仍然会加载 AdminModule —— 即使用户无法访问它的任何一个组件。 理想的方式是，只有在用户已登录的情况下你才加载 AdminModule。
   * https://angular.cn/guide/router#canload-guard-guarding-unauthorized-loading-of-feature-modules
   */
  canLoad(route: Route): boolean {
    const url = `/${route.path}`;
    return this.checkLogin(url);
  }
}
